package com.handler.http.message.config;

import com.alibaba.fastjson.JSON;
import com.handler.http.message.annotations.IgnoreEncrypt;
import com.handler.http.message.constants.Constant;
import com.handler.http.message.response.ResultWrapper;
import com.handler.http.message.util.sign.RSAUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Objects;

/**
 * @author guoQ.z
 * @date 2020/12/29 18:03
 * 对返回数据进行  加密
 */
@Slf4j
@RestControllerAdvice
public class EncryptResponseBodyAdvice implements ResponseBodyAdvice<Object> {
    @Override
    public boolean supports(MethodParameter methodParameter, Class aClass) {
        System.out.println("EncryptResponseBodyAdvice :  into ....");
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass,
                                  ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {

        ResultWrapper resultWrapper = new ResultWrapper();

        if (Objects.requireNonNull(methodParameter.getMethod()).isAnnotationPresent(IgnoreEncrypt.class)) {
            return body;
        }

        String type = mediaType.getType();
        if (MediaType.APPLICATION_JSON.getType().equalsIgnoreCase(type)) {
            try {
                log.info("返回被加密的内容:{}", body);
                body = RSAUtils.encryptByPrivateKey(JSON.toJSONString(body), Constant.PRIVATE_KEY);
                log.info("返回加密内容:{}", body);
            } catch (Exception e) {
                log.error("返回的response：错误信息:{}", e.getMessage());
                body = "加密失败，请重试";
            }
        }
        return body;
    }
}
